package com.jdy.haoduoaiteacher.view.visualizer;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Fake frequency distribution bar view.
 * 
 * @author zp @ 2015-7-24 下午5:50:35
 */
public class FrequencyDistributionBarView extends View {

  private final int SEGMENT_COUNT_DEFAULT = 4;

  private List<Range> mFrequenceRangeList;

  private int controlWidth;

  private int controlHeight;

  private int xoffset;

  private int yoffset;

  private final int NORMAL_BAR_COLOR = Color.argb(255, 255, 255, 255);

  private final int LOWER_POWER_BAR_COLOR = Color.argb(255, 255, 94, 66);

  public class Range {

    float start;

    float end;

    float min;

    float max;

    float value;

    int color;
  }

  public FrequencyDistributionBarView(Context context, AttributeSet attrs,
      int defStyle) {
    super(context, attrs, defStyle);
    init();
    // TODO Auto-generated constructor stub
  }

  public FrequencyDistributionBarView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    // TODO Auto-generated constructor stub
  }

  //
  // public FrequencyDistributionBarView(Context context) {
  // this(context, null);
  // // TODO Auto-generated constructor stub
  // }

  public void init() {
    mFrequenceRangeList = new ArrayList<Range>(SEGMENT_COUNT_DEFAULT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int desiredWidth = 45;
    int desiredHeight = 40;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    // Measure Width
    if (widthMode == MeasureSpec.EXACTLY) {
      // Must be this size
      width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
      // Can't be bigger than...
      width = Math.min(desiredWidth, widthSize);
    } else {
      // Be whatever you want
      width = desiredWidth;
    }

    // Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
      // Must be this size
      height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
      // Can't be bigger than...
      height = Math.min(desiredHeight, heightSize);
    } else {
      // Be whatever you want
      height = desiredHeight;
    }

    // MUST CALL THIS
    setMeasuredDimension(width + 10, height + 20);
  }

  @Override
  protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
    super.onSizeChanged(xNew, yNew, xOld, yOld);
    this.controlWidth = xNew + 10;
    this.controlHeight = yNew + 20;
    initRangeList(SEGMENT_COUNT_DEFAULT);
  }

  private void initRangeList(int totalSegment) {

    mFrequenceRangeList = new ArrayList<Range>(totalSegment);
    int totalHPadding = this.getPaddingLeft() + this.getPaddingRight();
    int totalVPadding = this.getPaddingBottom() + this.getPaddingTop();
    float segmentWidth = (this.controlWidth - totalHPadding) / totalSegment;
    int maxSegmentHeight = this.controlHeight - totalVPadding;
    float gapBetweenSeg = 8;
    for (int i = 0; i < totalSegment; i++) {
      Range r = new Range();
      r.color = getColorByIndex(i, NORMAL_BAR_COLOR);
      r.start = i * segmentWidth;
      r.end = r.start + segmentWidth - gapBetweenSeg;
      r.value = randInt(0, maxSegmentHeight);
      r.min = 0;
      r.max = maxSegmentHeight;
      mFrequenceRangeList.add(r);
    }
    Timer redrawTimer = new Timer();
    redrawTimer.schedule(new TimerTask() {

      @Override
      public void run() {

        postInvalidate();
      }
    }, 0, 200);
  }

  // public void switchToNormalColor() {
  // for (Range r : mFrequenceRangeList) {
  // r.color = NORMAL_BAR_COLOR;
  // }
  // invalidate();
  // }
  //
  // public void switchToLowerPowerColor() {
  // for (Range r : mFrequenceRangeList) {
  // r.color = LOWER_POWER_BAR_COLOR;
  // }
  // invalidate();
  // }

  public boolean isPlaying;

  public boolean isPlaying() {
    return isPlaying;
  }

  public void setPlaying(boolean isPlaying) {
    this.isPlaying = isPlaying;
  }

  private void randomFrequencyList() {

    if (isPlaying) {
      for (Range r : mFrequenceRangeList) {
        r.value = randInt((int) r.min, (int) r.max);
      }
    } else {

      for (int i = 0; i < mFrequenceRangeList.size(); i++) {
        Range r = mFrequenceRangeList.get(i);

        switch (i) {
        case 0:
          r.value = r.max - 50;
          break;
        case 1:
          r.value = 10;
          break;
        case 2:
          r.value = r.max - 45;
          break;
        case 3:
          r.value = 15;
          break;

        default:
          break;
        }

      }

    }

  }

  public int randInt(int min, int max) {

    // NOTE: Usually this should be a field rather than a method
    // variable so that it is not re-seeded every call.
    Random rand = new Random();

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
  }

  private int getColorByIndex(int i, int color) {
    switch (i) {
    case 0:
      return color;
    case 1:
      return color;
    case 2:
      return color;
    case 3:
      return color;
    case 4:
      return color;
    default:
      return color;
    }
  }

  @Override
  protected void onDraw(Canvas canvas) {
    drawRangeList(canvas);
  }

  private void drawRangeList(Canvas canvas) {
    Paint paint = new Paint();
    randomFrequencyList();
    for (Range r : mFrequenceRangeList) {
      paint.setColor(r.color);
      canvas.drawRect(r.start, r.value, r.end, r.max, paint);
    }
  }

}
